﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;

using ActiproSoftware.Windows.Controls.Docking;

using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.Unity;

namespace SupremacyEditor.RacesModule
{
    public interface IRaceDatabaseView
    {
        void ShowView();
        IEnumerable<IRacePresentationModel> Races { get; set; }
        IRacePresentationModel SelectedRace { get; set; }
        event EventHandler<DataEventArgs<IRacePresentationModel>> RaceSelected;
    }

    public interface IRaceDatabaseController
    {
        IRaceDatabaseView View { get; }
        void SelectRace(IRacePresentationModel race);
        void Run();
    }

    public class RaceDatabaseController : IRaceDatabaseController
    {
        private readonly IUnityContainer _container;
        private readonly DelegateCommand<object> _deleteCommand;
        private readonly ObservableKeyedCollection<string, IRacePresentationModel> _races;
        private IRegion _region;
        private ToolWindow _racesToolWindow;

        public RaceDatabaseController(IUnityContainer container)
        {
            _container = container;
            _races = _container.Resolve<IGameDataModel>().Races;

            _deleteCommand = new DelegateCommand<object>(
                ExecuteDeleteCommand,
                CanExecuteDeleteCommand);

            EditorCommands.DeleteItem.RegisterCommand(_deleteCommand);

            CommandManager.RequerySuggested += (sender, e) => RequeryCommands();
        }

        private bool CanExecuteDeleteCommand(object t)
        {
            return (_region != null)
                   && _region.ActiveViews.Contains(_racesToolWindow)
                   && (this.View.SelectedRace != null);
        }

        private void ExecuteDeleteCommand(object obj)
        {
            _races.Remove(this.View.SelectedRace);
        }

        private void RequeryCommands()
        {
            _deleteCommand.RaiseCanExecuteChanged();
        }

        #region Implementation of IRaceDatabaseController
        public IRaceDatabaseView View { get; private set; }

        public void SelectRace(IRacePresentationModel race)
        {
            View.SelectedRace = race;
        }

        public void Run()
        {
            _region = _container.Resolve<IRegionManager>().Regions[RegionNames.DockSite];

            this.View = _container.Resolve<IRaceDatabaseView>();
            this.View.Races = _races;
            this.View.RaceSelected += (sender, e) => RequeryCommands();

            _racesToolWindow = new ToolWindow
                               {
                                   Name = "RacesToolWindow",
                                   Title = "Races",
                                   Content = this.View
                               };

            _region.ActiveViews.CollectionChanged += (sender, e) => RequeryCommands();

            _region.Add(
                _racesToolWindow,
                "RaceDatabaseView",
                false);

            var dockSiteActiveWindowDescriptor = DependencyPropertyDescriptor.FromProperty(
                DockSite.ActiveWindowProperty,
                typeof(DockSite));

            if ((dockSiteActiveWindowDescriptor != null) && (_racesToolWindow.DockSite != null))
            {
                dockSiteActiveWindowDescriptor.AddValueChanged(
                    _racesToolWindow.DockSite,
                    (o, e) => _deleteCommand.IsActive = (_racesToolWindow.DockSite.ActiveWindow == _racesToolWindow));
            }

            this.View.ShowView();
        }
        #endregion
    }
}
